import React, { Component } from 'react';
import { render } from 'react-dom';
import './index.less';
/**
 * type  类型 success | error | info
 * duration 持续时间 默认 4000 毫秒
 * content 提示内容
 */

let message_obj = {},
  id = 0,
  root = null,
  showClassName = 'free-message-item-show',
  hideClassName = 'free-message-item-hide';

class FreeMessage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isHover: false, // 是否鼠标hover状态
    };
  }

  timeoutId = null;

  componentDidMount() {
    const {
      dataInfo: { stay, cancleAutoClose },
    } = this.props;
    this._unmounted = false;
    setTimeout(() => {
      !stay && !cancleAutoClose && this.startTimeout();
      this.startAnimation(true);
    }, 20);
  }

  componentWillUnmount() {
    this._unmounted = true;
  }

  cleartimeout = () => {
    if (this.timeoutId) {
      this.timeoutId = null;
      clearTimeout(this.timeoutId);
    }
  };

  // 鼠标移入，清除倒计时
  onMouseenter = () => {
    this.cleartimeout();
    this.setState({
      isHover: true,
    });
  };

  // 鼠标移出，继续倒计时
  onMouseleave = () => {
    const {
      dataInfo: { cancleAutoClose, afterHoverClose },
    } = this.props;
    this.setState({
      isHover: false,
    });
    this.cleartimeout();
    !this.timeoutId &&
      (!cancleAutoClose || afterHoverClose || +afterHoverClose === 1) &&
      this.startTimeout();
  };

  startAnimation = (isShow) => {
    if (isShow) {
      this.contentBox.classList.add(showClassName);
    } else {
      this.contentBox.classList.remove(showClassName);
      this.contentBox.classList.add(hideClassName);
    }
  };

  startTimeout = () => {
    const {
      dataInfo: { duration, id },
    } = this.props;

    this.timeoutId = setTimeout(() => {
      if (!this.state.isHover && !this._unmounted) {
        this.startAnimation(false);
        setTimeout(() => {
          !this.state.isHover && this.ownUnMount(id);
        }, 500);
      }
    }, duration || 4000);
  };

  ownUnMount = (id) => {
    const {
      dataInfo: { callback },
    } = this.props;
    delete message_obj[id];
    renderMessageEl(message_obj, root);
    callback && callback();
  };

  onClose = (id) => {
    clearTimeout(this.timeoutId);
    this.startAnimation(false);
    setTimeout(() => {
      this.ownUnMount(id);
    }, 500);
  };

  renderFreeMessage = () => {
    const {
        dataInfo: { content, type, id, customClass, hideClose, dom },
      } = this.props,
      isCustom = type === 'custom' ? customClass : '';
    return (
      <div
        id={dom}
        className={`free-message-item ${
          isCustom ? 'custom-free-message' : ''
        } ${isCustom || type || 'success'}-free-message`}
        ref={(ref) => (this.contentBox = ref)}
        onMouseEnter={this.onMouseenter}
        onMouseLeave={this.onMouseleave}
      >
        <div
          className={`free-message-item-left-line ${
            type || 'success'
          }-free-message-left-line`}
        ></div>
        {hideClose && +hideClose === 1 ? null : (
          <div className='close-btn' onClick={this.onClose.bind(this, id)}>
            &times;
          </div>
        )}
        <div
          className={`free-message-item-icon ${
            type || 'success'
          }-free-message-item-icon`}
        >
          {type === 'error' ? (
            <i className='iconfont'>&#xe650;</i>
          ) : type === 'info' ? (
            <i className='iconfont'>&#xe6f6;</i>
          ) : (
            <i className='iconfont'>&#xe64b;</i>
          )}
        </div>
        <div className='free-message-item-content'>{content}</div>
      </div>
    );
  };

  render() {
    return this.renderFreeMessage();
  }
}

/**
 *
 * @param {*content}    string
 * @param {*type}       string
 * @param {*duration}   number
 * @param {*callback}   function
 * @param {*stay}       boolean
 */

export function freeMessage({
  content,
  type,
  duration,
  callback,
  stay,
  customClass,
  cancleAutoClose,
  afterHoverClose,
  hideClose,
  dom,
}) {
  if (!root) {
    root = document.createElement('div');
    root.setAttribute('id', 'free-message-box');
    document.querySelector('body').appendChild(root);
  }
  message_obj[id] = (
    <FreeMessage
      key={id}
      dataInfo={{
        content,
        type,
        duration,
        callback,
        id,
        stay,
        customClass,
        cancleAutoClose,
        afterHoverClose,
        hideClose,
        dom,
      }}
    />
  );
  id++;
  renderMessageEl(message_obj, root);
}

function renderMessageEl(message_obj, root) {
  let reactEl = [];
  for (let key in message_obj) {
    reactEl.push(message_obj[key]);
  }
  render(reactEl, root);
}
